package com.tianbao54.concurrent.condition;

import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

class Warehouse {

    private static final int MAX_SIZE = 10;
    private static volatile Product [] array = new Product[MAX_SIZE];
    private static final AtomicInteger currentSize = new AtomicInteger(0);

    public synchronized void add (Product product)   {

        while (currentSize.get() == MAX_SIZE) {
            try {
                System.out.println("仓库已满，开始等待，不能放入新产品");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("生者了一个产品：" + product + " 当前仓库剩余空位：" + (MAX_SIZE - currentSize.get()));
        this.notifyAll();
        array[currentSize.getAndIncrement()] = product;
    }

    public synchronized Product del () {
        while (currentSize.get() == 0)
            try {
                System.out.println("仓库已空，开始等待放入产品");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        this.notifyAll();
        Product product = array[currentSize.decrementAndGet()];
        System.out.println("取出了一个产品：" + product + " 当前仓库剩余空位：" + (MAX_SIZE - currentSize.get()));
        return product;
    }
}

class Product {

    private String id;

    public Product(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "id " + id;
    }
}

public class Client {

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(20);
        Warehouse warehouse = new Warehouse();

        for (int i = 0 ; i < 2 ; i ++) {
            executorService.submit(() -> {
                while (true) {
                    warehouse.add(new Product(UUID.randomUUID().toString()));
                    TimeUnit.SECONDS.sleep(1);
                }
            });
        }

//        for (int i = 0 ; i < 10 ; i ++) {
            executorService.submit(() -> {
                while (true) {
                    Product product = warehouse.del();
                    TimeUnit.SECONDS.sleep(1);
                }
            });
//        }
    }
}